﻿using System;
using System.Collections.Concurrent;
using UMC.Data;
using System.Text;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using UMC.Net;
using System.Threading.Tasks;

namespace UMC.ITME
{

    class LogSetting : UMC.Data.DataProvider
    {

        static int Mtu = Int32.MaxValue;
        static LogSetting()
        {

            // 获取所有网络接口
            NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

            foreach (NetworkInterface networkInterface in networkInterfaces)
            {
                // 确保网络接口已启用并支持IPv4
                if (networkInterface.OperationalStatus == OperationalStatus.Up &&
                    networkInterface.Supports(NetworkInterfaceComponent.IPv4))
                {
                    // 获取并打印MTU
                    int mtu = networkInterface.GetIPProperties().GetIPv4Properties().Mtu;
                    if (mtu < Mtu)
                    {
                        Mtu = mtu;
                    }
                }
            }

        }
        UdpClient client;

        public static LogSetting Instance()
        {
            if (_Instance == null)
            {
                _Instance = new LogSetting();
                _Instance.LoadConf();
            }
            return _Instance;
        }

        static LogSetting _Instance;

        bool _isWriter = false;
        public virtual bool IsWriter
        {
            get
            {
                return _isWriter;
            }
        }
        public void LoadConf()
        {
            var provider = Reflection.Configuration("assembly")?["Log"];
            if (provider != null)
            {
                var host = provider["host"];
                if (String.IsNullOrEmpty(host) == false)
                {
                    var port = Utility.IntParse(provider["port"], 514);
                    _isWriter = Mtu > 512;
                    this.client = new UdpClient(host, port);
                }
                else
                {
                    this.client?.Dispose();
                    _isWriter = false;
                }
            }
            else
            {
                this.client?.Dispose();
                _isWriter = false;
            }

        }

        uint logIndex = 0;
        public virtual async void Write(String[] logs, int offset, int size)
        {
            var buffers = System.Buffers.ArrayPool<Byte>.Shared.Rent(Mtu);
            var h = logIndex++;
            String root = logs[0];

            for (var i = 1; i < size; i += 2)
            {

                var log = logs[i + 1];
                if (String.IsNullOrEmpty(log) == false)
                {
                    int index = 0;
                    index += $"<13>{DateTime.Now:u} {root} {logs[i]}[{h}]:".WriteBytes(buffers, index);
                    for (var c = 0; c < log.Length; c++)
                    {
                        index += Encoding.UTF8.GetBytes(log, c, 1, buffers, index);
                        if (index + 5 > Mtu)
                        {
                            break;
                        }
                    }
                    try
                    {
                        await this.client.SendAsync(buffers.AsMemory(0, index));
                    }
                    catch (Exception ex)
                    {
                        Utility.Error("Syslog", ex.ToString());
                    }
                }
            }
            System.Buffers.ArrayPool<Byte>.Shared.Return(buffers);
        }
        public static void Instance(LogSetting logSetting, Provider provider)
        {
            logSetting.Provider = provider;
            _Instance = logSetting;
        }
    }
}

